Talk:Casting Cost/@comment-2001:14BB:420:1D7B:E8FA:A1D6:E379:D063-20180702070218/@comment-1333593-20180704223759
bp is the (16bit) base pointer register in the x86 processsor architecture. It is commonly used by subfunctions to set a reference point so that passed arguments and local variables can be accessed more easily (all of these are on the stack). Typically, the first instruction of the routine will be a "push bp", followed by "mov bp, sp" (set bp to the current stack pointer value), then "sub sp, X" (the stack grows downward), where X is the stack frame size allocated to local vars. Things below bp are local and will be automatically ditched when the function pops the old value back before returning. Above bp is usually the return address, and above that are the arguments passed to this function. These usually exist either as local variables in the parent function, global variables, or immediate values. They are passed by value on the stack, so modifying them will not alter anything in the parent function's frame, but if there are later references to them in the routine in question, those will be affected. In our specific case, if there are unknown spells of any rarity, execution will pass to a block that first checks if a spell of that rarity can be awarded from the book just found, and if so, gives one at random. Afterwards, it decrements the array element for that book and rarity. The advantage of setting up the amount-per-rarity-per-book array within the function is probably that main memory is a more scarce resource than cycles, and this function is in an overlay, so will only sit in memory when needed. Not that those 80 bytes really would have mattered if other things were properly optimized, but that's a topic for another discussion. Anyway, because the table is reset (and reallocated locally) every time the function is called, it's ideal for use as a "remaining spells to award" variable, which then doesn't have to be set up separately. If the bound check was done properly, it would simply have been a case of not receiving any spells at 10+ books, so the last two Very Rares would have had to be found differently, but the book benefits could still be gained without trouble. This way though, when the function checks whether a spell of a certain rarity can be awarded with 11 books, it will look at the return address (low/high word), player index, and book color respectively for C/UC/R/VR spells, and award a spell if these are positive. After this, it decrements that value, and I think it actually keeps going until the value is zero or negative regardless of whether all possible spells are already given or not. On a side note, I think this routine is not a far call, which means that one of the return address words is not actually used when returning from it (but will be set to the code segment address regardless), so either the C or UC spells will not cause a crash. It should also be possible to map out the stack frame of the parent function to find out what variables control the 12th book. I know the bottom of that frame is the parent's local book color variable, but anything pushed on the stack before making the call will be inbetween. That is at least two registers originating from the parent's parent, and I didn't yet look at what they store.